type JSDynamicObject = any;
function verifyProperty (obj : JSDynamicObject, name : string, desc ? : any, options ? : any) : boolean {
    var originalDesc : any = Object.getOwnPropertyDescriptor (obj, name);
    var nameStr : string = String (name);
    if (desc === undefined) {
        return true;
    }
    var failures : any [] = [];
    if (Object.prototype.hasOwnProperty.call (desc, 'value')) {
        if (desc.value !== originalDesc.value) {
            failures.push ("descriptor value should be " + desc.value);
        }
    }
    if (Object.prototype.hasOwnProperty.call (desc, 'enumerable')) {
        if (desc.enumerable !== originalDesc.enumerable || desc.enumerable !== isEnumerable (obj, name)) {
            failures.push ('descriptor should ' + (desc.enumerable ? '' : 'not ') + 'be enumerable');
        }
    }
    if (Object.prototype.hasOwnProperty.call (desc, 'writable')) {
        if (desc.writable !== originalDesc.writable || desc.writable !== isWritable (obj, name)) {
            failures.push ('descriptor should ' + (desc.writable ? '' : 'not ') + 'be writable');
        }
    }
    if (Object.prototype.hasOwnProperty.call (desc, 'configurable')) {
        if (desc.configurable !== originalDesc.configurable || desc.configurable !== isConfigurable (obj, name)) {
            failures.push ('descriptor should ' + (desc.configurable ? '' : 'not ') + 'be configurable');
        }
    }
    if (options && options.restore) {
        Object.defineProperty (obj, name, originalDesc);
    }
    return true;
}
function isEnumerable (obj : JSDynamicObject, name : any) : any {
    var stringCheck : boolean = false;
    if (typeof name === "string") {
        for (var x in obj) {
            if (x === name) {
                stringCheck = true;
                break;
            }
        }
    } else {
        stringCheck = true;
    }
    return stringCheck && Object.prototype.hasOwnProperty.call (obj, name) && Object.prototype.propertyIsEnumerable.call (obj, name);
}
function isWritable (obj : JSDynamicObject, name : string, verifyProp ? : any, value ? : any) : any {
    var newValue : any = value || "unlikelyValue";
    var hadValue : any = Object.prototype.hasOwnProperty.call (obj, name);
    var oldValue : any = obj [name];
    var writeSucceeded ! : any;
    try {
        obj [name] = newValue;
    }
    catch (e : any) {
        if (! (e instanceof TypeError)) {
        }
    }
    writeSucceeded = isEqualTo (obj, verifyProp || name, newValue);
    if (writeSucceeded) {
        if (hadValue) {
            obj [name] = oldValue;
        } else {
            delete obj [name];
        }
    }
    return writeSucceeded;
}
function isEqualTo (obj : JSDynamicObject, name : any, expectedValue : any) : void {
    var actualValue : any = obj [name];
}
function isConfigurable (obj : JSDynamicObject, name : string) : boolean {
    try {
        delete obj [name];
    }
    catch (e : any) {
        if (! (e instanceof TypeError)) {
        }
    }
    return ! Object.prototype.hasOwnProperty.call (obj, name);
}
var o : JSDynamicObject = {
    a : 1,
    b : 2
};
console.log (verifyProperty (o, "o"));
